
/*主要实现了一个配置信息单例类,可以从配置文件读取配置信息,通过单例类全局获取*/

#ifndef __CONFIG_HPP__
#define __CONFIG_HPP__

#include <iostream>
#include <string>
#include <mutex>
#include <unistd.h>
#include <sys/types.h>
#include "util.hpp"

/*
{
    "server_port" : 9090,
    "server_ip" : "0.0.0.0",
    "tmp_path": "/var/lib/mysql-files/",
    "download_prefix" : "/download/",
    "packfile_suffix" : ".lz",
    "sql_host" : "localhost",
    "sql_user" : "root",
    "sql_passwd" : "molijun1@",
    "sql_database" : "cloud",
    "file_table" : "packfile",
    "content_table": "file_content"
    "sql_port" : 3306
}
*/

namespace cloud
{
#define CONFIG_FILE "./cloud.conf"
    class Config
    {
    private:
        int _server_port;
        int _sql_port;
        std::string _server_ip;
        std::string _sql_host;
        std::string _sql_user;        // 数据库用户名
        std::string _sql_passwd;      // 数据库密码
        std::string _sql_database;    // 数据库名
        std::string _file_table;      // 文件表
        std::string _content_table;   // 内容表
        std::string _download_prefix; // 下载任务url前缀
        std::string _packfile_suffix; // 压缩文件后缀名
        std::string _tmp_path;        // 文件暂时存放路径
        std::string _redis_url;

    private:
        static std::mutex _mutex;
        static Config *_instance;
        Config()
        {
            // 默认使用的配置信息文件,也可以自定义配置文件
            ReadConfig(CONFIG_FILE);
        }

    public:
        bool ReadConfig(const std::string &filename)
        {
            // 获取配置文件
            Json::Value root;
            std::string conf_content;
            FileUtil conf(filename);
            if (conf.GetContent(&conf_content) == false)
                return false;
            if (JsonUtil::UnSerialize(root, &conf_content) == false)
                return false;

            // 获取配置信息
            _server_port = root["server_port"].asInt();
            _server_ip = root["server_ip"].asCString();
            _sql_port = root["sql_port"].asInt();
            _sql_host = root["sql_host"].asCString();
            _sql_user = root["sql_user"].asCString();
            _sql_passwd = root["sql_passwd"].asCString();
            _sql_database = root["sql_database"].asCString();
            _file_table = root["file_table"].asCString();
            _content_table = root["content_table"].asCString();
            _download_prefix = root["download_prefix"].asCString();
            _packfile_suffix = root["packfile_suffix"].asCString();
            _redis_url = root["redis_url"].asCString();
            _tmp_path = root["tmp_path"].asCString();

            return true;
        }

        int GetServerPort() { return _server_port; }
        std::string GetServerIp() { return _server_ip; }
        int GetSqlPort() { return _sql_port; }
        std::string GetSqlHost() { return _sql_host; }
        std::string GetSqlUser() { return _sql_user; }
        std::string GetSqlPassword() { return _sql_passwd; }
        std::string GetSqlDataBase() { return _sql_database; }
        std::string GETFileTable() { return _file_table; };
        std::string GetContentTable() { return _content_table; }
        std::string GetDownloadPrefix() { return _download_prefix; }
        std::string GetPackFileSuffix() { return _packfile_suffix; }
        std::string GetTmpPath() { return _tmp_path; }
        std::string GetRedisURL() { return _redis_url; }

    public:
        static Config *GetInstance()
        {
            if (_instance == nullptr) // 双重判断减少加锁解锁次数,提高性能
            {
                _mutex.lock();
                if (_instance == nullptr)
                    _instance = new Config();
                _mutex.unlock();
            }

            return _instance;
        }
    };
    Config *Config::_instance = nullptr;
    std::mutex Config::_mutex;
}; // namespace cloud

#endif //__CONFIG_HPP__